﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Diploma.Models.Entities;
using Diploma.Models.IRepositories;

namespace Diploma.Models.Repositories
{
    internal class CompaniesRepository : ICompaniesRepository
    {
        private readonly DiplomaEntities dataContext;

        public CompaniesRepository(DiplomaEntities dataContext)
        {
            this.dataContext = dataContext;
        }

        #region Implementation of ICompaniesRepository

        public IEnumerable<Company> GetAll()
        {
            return dataContext.Companies;
        }

        public IEnumerable<Company> GetAllForLevel(int levelId)
        {
            return dataContext.CompaniesForQualificationLevels.Where(r => r.QualificationLevelId == levelId).Select(r => r.Company);
        }

        public Company Get(Guid companyId)
        {
            return dataContext.Companies.FirstOrDefault(r => r.Id == companyId);
        }

        public void Add(string name)
        {
            var company = new Company
                              {
                                  Id = Guid.NewGuid(),
                                  DisplayName = name
                              };
            dataContext.Companies.AddObject(company);
            dataContext.SaveChanges();
        }

        public void UpdateCompanyName(Guid companyId, string name)
        {
            var company = Get(companyId);
            company.DisplayName = name;
            dataContext.SaveChanges();
        }

        public void Delete(Guid companyId)
        {
            var company = Get(companyId);
            if (company != null)
            {
                //Update Students
                var students = DataManager.Instance.StudentsRepository.GetStudents().Where(r => r.CollaborationRoom != null && r.CollaborationRoom.PracticePlace == companyId);
                foreach (Student s in students)
                {
                    s.CollaborationRoom.PracticePlace = null;
                }

                //Delete from Lecturers
                DataManager.Instance.CompaniesRepository.DetachCompanyFromLevels(companyId);

                var lecturerInCompanies = dataContext.LecturerInCompanies.Where(r => r.CompanyId == companyId);
                foreach (var lecturerInCompany in lecturerInCompanies)
                {
                    dataContext.LecturerInCompanies.DeleteObject(lecturerInCompany);
                }

                //Delete object
                dataContext.Companies.DeleteObject(company);
                dataContext.SaveChanges();
            }
        }

        public void AttachCompanyToLevel(Guid companyId, int levelId, int? maxValue)
        {
            var companyForLevel = new CompaniesForQualificationLevel
                                      {
                                          Id = Guid.NewGuid(),
                                          CompanyId = companyId,
                                          QualificationLevelId = levelId,
                                          MaxSudents = maxValue
                                      };
            dataContext.CompaniesForQualificationLevels.AddObject(companyForLevel);
            dataContext.SaveChanges();
        }

        public void DetachCompanyFromLevel(Guid companyId, int levelId)
        {
            var companyForLevel =
                dataContext.CompaniesForQualificationLevels.FirstOrDefault(
                    r => r.CompanyId == companyId && r.QualificationLevelId == levelId);
            if(companyForLevel != null)
            {
                dataContext.CompaniesForQualificationLevels.DeleteObject(companyForLevel);
                dataContext.SaveChanges();
            }
        }

        public void DetachCompanyFromLevels(Guid companyId)
        {
            var companyForLevel = dataContext.CompaniesForQualificationLevels.Where(r => r.CompanyId == companyId);
            foreach (CompaniesForQualificationLevel c in companyForLevel)
            {
                dataContext.CompaniesForQualificationLevels.DeleteObject(c);
            }
            dataContext.SaveChanges();
        }
        
        public IEnumerable<LecturerInCompanyEntity> LecturerInCompanies(Guid lecturerId)
        {
            var result = new List<LecturerInCompanyEntity>();

            foreach(var item in dataContext.LecturerInCompanies.Where(r => r.LecturerId == lecturerId))
            {
                var company = Get(item.CompanyId);
                var model = new LecturerInCompanyEntity
                                {
                                    LecturerId = lecturerId,
                                    CompanyId = company.Id,
                                    CompanyName = company.DisplayName,
                                    LevelId = item.LevelId
                                };
                result.Add(model);
            }

            return result;
        }

        public void AttachCompanyToLecturer(Guid lecturerId, Guid companyId, int levelId)
        {
            var isDublicate = dataContext.LecturerInCompanies
                            .FirstOrDefault(r => r.LecturerId == lecturerId && r.CompanyId == companyId && r.LevelId == levelId) != null;
            if (!isDublicate)
            {
                var model = new LecturerInCompany
                                {
                                    CompanyId = companyId,
                                    LecturerId = lecturerId,
                                    LevelId = levelId
                                };
                dataContext.LecturerInCompanies.AddObject(model);
                dataContext.SaveChanges();
            }
        }

        public void DetachCompanyToLecturer(Guid lecturerId, Guid companyId, int levelId)
        {
            var model = dataContext.LecturerInCompanies
                            .FirstOrDefault(r => r.LecturerId == lecturerId && r.CompanyId == companyId && r.LevelId == levelId);
            if (model != null)
            {
                dataContext.LecturerInCompanies.DeleteObject(model);
                dataContext.SaveChanges();
            }
        }

        #endregion
    }
}
